
#import	<stdlib.h>
#import	<libc.h>
#import	<math.h>
#import	<time.h>
#import <sys/time.h>
#import	<appkit/Application.h>
#import	<appkit/Slider.h>
#import	<appkit/Button.h>
#import	<appkit/NXImage.h>
#import	<dpsclient/wraps.h>
#import	"TanCircleView.h"

@implementation TanCircleView

/**********************************************************************/

- ( int ) distance : ( int ) x : ( int ) y : ( int ) i
{
	int	xdist;
	int	ydist;
	int	distsq;
	
	xdist = x - Circles[ i ].x;
	ydist = y - Circles[ i ].y;
	distsq = xdist * xdist + ydist * ydist;
	
	return ( sqrt( distsq ) - Circles[ i ].r );
}

/**********************************************************************/

- ( int ) newRadius : ( int ) x : ( int ) y
{
	int	i;
	int	radius;
	
	radius = MaxRadius;
	
	for( i = 0; i < CurCircle; ++i )
	{
		radius = MIN( radius, [ self distance:x:y:i ] );
		
		if( radius <= 0 )
			break;
	}
	
	return radius;
}

/**********************************************************************/

- ( const char * ) windowTitle
{
	return ( const char * ) "Tangent Circles";
}

/**********************************************************************/

- newWindow
{
	[ self genFirstCircle ];
	CurCircle = 1;
	
	return self;
}

/**********************************************************************/ 

- initFrame : ( const NXRect * ) frameRect
{
	[ super initFrame : frameRect ];
	
	[ self setOpaque : YES ];
	
	CurCircle = MAXCIRCLES;
	
	return self;
}

/**********************************************************************/

- sizeTo : ( NXCoord ) width : ( NXCoord ) height
{
	[ super sizeTo : width : height ];
	
	[ self genFirstCircle ];
	
	return self;
}

/**********************************************************************/

- drawSelf : ( NXRect * ) r : ( int ) count
{
	if ( !r || !count )
		return self;
		
	PSsetgray( NX_BLACK );
	
	NXRectFill( r );
	
	return self;
}

/**********************************************************************/

- genFirstCircle
{
	struct	timeval		tp;
	struct	timezone	tzp;
	
	CurColor = MINCOLOR;

	gettimeofday( &tp, &tzp );
	
	srandom( ( int ) tp.tv_sec );
	
	Max_X = bounds.size.width;
	Max_Y = bounds.size.height;

	MaxRadius = MAX( Max_X, Max_Y );
	MaxRadius /= 8;
		
	X_pos = ( int ) ( random( ) % Max_X );
	Y_pos = ( int ) ( random( ) % Max_Y );
	Radius = ( int ) ( random( ) % MaxRadius );
	
	Circles[ 0 ].x = X_pos;
	Circles[ 0 ].y = Y_pos;
	Circles[ 0 ].r = Radius;
	
	return self;
}

/**********************************************************************/

- oneStep
{
	if( ++CurCircle >= MAXCIRCLES )
	{
		CurCircle = 1;
		[ self genFirstCircle ];
// 		[ self display ];
	}
	
	do
	{
		X_pos = ( int ) ( random( ) % Max_X );
		Y_pos = ( int ) ( random( ) % Max_Y );
		Radius = [ self newRadius : X_pos : Y_pos ];
	}
	while ( Radius <= 0 );
		
	Radius = MIN( MaxRadius, Radius );
	
	PSnewpath( );	
	PSsetgray( CurColor );
	PSarc( X_pos, Y_pos, Radius, 0, 360 );
	PSfill( );
		
	Circles[ CurCircle ].x = X_pos;
	Circles[ CurCircle ].y = Y_pos;
	Circles[ CurCircle ].r = Radius;
	
	CurColor = ( CurColor >= MAXCOLOR ) ? MINCOLOR : CurColor + COLORINC;
	
	return self;
}

/**********************************************************************/

@end
